package com.first.nell.network

import com.first.nell.data.*
import com.google.gson.JsonObject
import com.first.nell.extend.toFirstNellFullFirstNellUrlFirstNellPath
import okhttp3.MultipartBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.http.Part
import retrofit2.http.QueryMap
import java.lang.RuntimeException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

object ApiUserNetwork {

    private val garlic_loanServiceApi = ApiServiceCreator.create<ApiUserService>()

    /** 获取启动配置 */
    suspend fun fetchFirstNellGlobalFirstNellConfig(reqZone: ReqZone) =
        garlic_loanServiceApi.fetchFirstNellGlobalFirstNellConfig(
            ApiUrl.BASE_URL + ApiUrl.ZONE_PATH,
            reqZone.p,
            reqZone.tz
        ).await()

    suspend fun fetchFirstNellAppFirstNellConfig(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellAppFirstNellConfig(
            ApiUrl.NARSCASH_PATH_APP_CONFIG.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellAppFirstNellVersion(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellAppFirstNellVersion(
            ApiUrl.NARSCASH_PATH_APP_VERSION.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellOtp(reqDoLogin: ReqDoLogin) =
        garlic_loanServiceApi.fetchFirstNellOtp(
            ApiUrl.NARSCASH_PATH_SEND_OTP.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqDoLogin
        ).await()

    suspend fun doFirstNellLogin(reqDoLogin: ReqDoLogin) =
        garlic_loanServiceApi.doFirstNellLogin(
            ApiUrl.NARSCASH_PATH_OTP_LOGIN.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqDoLogin
        ).await()

    suspend fun fetchFirstNellUserFirstNellState(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellUserFirstNellState(
            ApiUrl.NARSCASH_PATH_USER_STATE.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellHomeFirstNellCredit(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellHomeFirstNellCredit(
            ApiUrl.NARSCASH_PATH_HOME_LIMIT.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellLoaningFirstNellDetail(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellLoaningFirstNellDetail(
            ApiUrl.NARSCASH_PATH_LOANING_DETAIL.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellRepayFirstNellDetail(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellRepayFirstNellDetail(
            ApiUrl.NARSCASH_PATH_REPAY_DETAIL.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellRepayFirstNellUrlFirstNellGHA(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellRepayFirstNellUrlFirstNellGHA(
            ApiUrl.NARSCASH_PATH_REPAY_URL_GHA.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellRepayFirstNellUrlFirstNellUGX(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellRepayFirstNellUrlFirstNellUGX(
            ApiUrl.NARSCASH_PATH_REPAY_URL_UGX.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellRepayFirstNellUrlFirstNellKSH(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellRepayFirstNellUrlFirstNellKSH(
            ApiUrl.NARSCASH_PATH_REPAY_URL_KSH.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellRepayFirstNellUrlFirstNellFCFA(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellRepayFirstNellUrlFirstNellFCFA(
            ApiUrl.NARSCASH_PATH_REPAY_URL_FCFA.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellRepayFirstNellUrlFirstNellVND(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellRepayFirstNellUrlFirstNellVND(
            ApiUrl.NARSCASH_PATH_REPAY_URL_VND.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun fetchFirstNellVirtualFirstNellAccount(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellVirtualFirstNellAccount(
            ApiUrl.NARSCASH_PATH_CREATE_VIRTUAL_ACCOUNT.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun initFirstNellPaystackFirstNellSdk(reqPaystackOrderInitNgn: ReqPaystackOrderInitNgn) =
        garlic_loanServiceApi.initFirstNellPaystackFirstNellSdk(
            ApiUrl.NARSCASH_PATH_INIT_PAYSTACK_SDK.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqPaystackOrderInitNgn
        ).await()

    suspend fun fetchFirstNellPaystackFirstNellCardFirstNellList(reqBase: ReqBase) =
        garlic_loanServiceApi.fetchFirstNellPaystackFirstNellCardFirstNellList(
            ApiUrl.NARSCASH_PATH_PAYSTACK_CARD_LIST.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun saveFirstNellFeedback(reqSaveFeedback: ReqSaveFeedback) =
        garlic_loanServiceApi.saveFirstNellFeedback(
            ApiUrl.NARSCASH_PATH_SAVE_FEEDBACK.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqSaveFeedback
        ).await()

    suspend fun saveFirstNellInfo(targetUrl: String, jsonObject: JsonObject) =
        garlic_loanServiceApi.saveFirstNellInfo(targetUrl, jsonObject).await()

    suspend fun saveFirstNellInfoFirstNellOcr(reqSaveOcrResultVnd: ReqSaveOcrResultVnd) =
        garlic_loanServiceApi.saveFirstNellInfoFirstNellOcr(
            ApiUrl.NARSCASH_PATH_SAVE_OCR_VND.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqSaveOcrResultVnd
        ).await()

    suspend fun saveFirstNellInfoFirstNellLiveness(reqSaveLivenessVnd: ReqSaveLivenessVnd) =
        garlic_loanServiceApi.saveFirstNellInfoFirstNellLiveness(
            ApiUrl.NARSCASH_PATH_SAVE_LIVENESS_VND.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqSaveLivenessVnd
        ).await()

    suspend fun startFirstNellLiveness(reqSaveLivenessVnd: ReqSaveLivenessVnd) =
        garlic_loanServiceApi.startFirstNellLiveness(
            ApiUrl.NARSCASH_PATH_START_LIVENESS_VND.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqSaveLivenessVnd
        ).await()

    suspend fun fetchFirstNellBankFirstNellCodeFirstNellList(reqGetBankList: ReqGetBankList) =
        garlic_loanServiceApi.fetchFirstNellBankFirstNellCodeFirstNellList(
            ApiUrl.NARSCASH_PATH_BANK_LIST.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqGetBankList
        ).await()

    suspend fun getFirstNellWalletFirstNellListFirstNellFCFA(reqBase: ReqBase) =
        garlic_loanServiceApi.getFirstNellWalletFirstNellListFirstNellFCFA(
            ApiUrl.NARSCASH_PATH_WALLET_LIST_FCFA.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun saveFirstNellWalletFirstNellFCFA(reqSaveWalletFcFa: ReqSaveWalletFcFa) =
        garlic_loanServiceApi.saveFirstNellWalletFirstNellFCFA(
            ApiUrl.NARSCASH_PATH_BIND_WALLET_FCFA.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqSaveWalletFcFa
        ).await()

    suspend fun deleteFirstNellWalletFirstNellFCFA(reqDeleteWalletFcfa: ReqDeleteWalletFcfa) =
        garlic_loanServiceApi.deleteFirstNellWalletFirstNellFCFA(
            ApiUrl.NARSCASH_PATH_DELETE_WALLET_FCFA.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqDeleteWalletFcfa
        ).await()

    suspend fun saveFirstNellBvnFirstNellFCFA(reqBase: ReqBase) =
        garlic_loanServiceApi.saveFirstNellBvnFirstNellFCFA(
            ApiUrl.NARSCASH_PATH_SAVE_BVN_FCFA.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun getFirstNellWalletFirstNellListFirstNellXaf(reqBase: ReqBase) =
        garlic_loanServiceApi.getFirstNellWalletFirstNellListFirstNellXaf(
            ApiUrl.NARSCASH_PATH_WALLET_LIST_XAF.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun saveFirstNellWalletFirstNellXaf(reqSaveWalletFcFa: ReqSaveWalletFcFa) =
        garlic_loanServiceApi.saveFirstNellWalletFirstNellXaf(
            ApiUrl.NARSCASH_PATH_BIND_WALLET_XAF.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqSaveWalletFcFa
        ).await()
    suspend fun deleteFirstNellWalletFirstNellXaf(reqDeleteWalletFcfa: ReqDeleteWalletFcfa) =
            garlic_loanServiceApi.deleteFirstNellWalletFirstNellXaf(
                ApiUrl.NARSCASH_PATH_DELETE_WALLET_XAF.toFirstNellFullFirstNellUrlFirstNellPath(),
                reqDeleteWalletFcfa
            ).await()
    suspend fun saveFirstNellBvnFirstNellXaf(reqBase: ReqBase) =
        garlic_loanServiceApi.saveFirstNellBvnFirstNellXaf(
            ApiUrl.NARSCASH_PATH_SAVE_BVN_XAF.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun createFirstNellLoan(reqBase: ReqBase) =
        garlic_loanServiceApi.createFirstNellLoan(
            ApiUrl.NARSCASH_PATH_LOAN_SUBMIT.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun checkFirstNellAppFirstNellReview(reqBase: ReqBase) =
        garlic_loanServiceApi.checkFirstNellAppFirstNellReview(
            ApiUrl.NARSCASH_PATH_CHECK_APP_REVIEW.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun uploadFirstNellImage(
        @QueryMap map: Map<String, String>,
        @Part file: MultipartBody.Part,
    ) =
        garlic_loanServiceApi.uploadFirstNellImage(
            ApiUrl.NARSCASH_PATH_UPLOAD_IMAGE.toFirstNellFullFirstNellUrlFirstNellPath(),
            map,
            file
        ).await()

    suspend fun startFirstNellOcr(reqDoOcrVnd: ReqDoOcrVnd) =
        garlic_loanServiceApi.startFirstNellOcr(
            ApiUrl.NARSCASH_PATH_IMAGE_OCR.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqDoOcrVnd
        ).await()

    suspend fun saveFirstNellImage(reqSaveImage: ReqSaveImage) =
        garlic_loanServiceApi.saveFirstNellImage(
            ApiUrl.NARSCASH_PATH_IMAGE_SAVE.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqSaveImage
        ).await()

    suspend fun startFirstNellSim(reqBase: ReqBase) =
        garlic_loanServiceApi.startFirstNellSim(
            ApiUrl.NARSCASH_PATH_START_SIM.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun saveFirstNellInfoFirstNellSim(reqBase: ReqBase) =
        garlic_loanServiceApi.saveFirstNellInfoFirstNellSim(
            ApiUrl.NARSCASH_PATH_SAVE_SIM.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqBase
        ).await()

    suspend fun checkFirstNellInfoFirstNellSim(reqSaveSimInfo: ReqSaveSimInfo) =
        garlic_loanServiceApi.checkFirstNellInfoFirstNellSim(
            ApiUrl.NARSCASH_PATH_VIET_SIM_INFO.toFirstNellFullFirstNellUrlFirstNellPath(),
            reqSaveSimInfo
        ).await()

    private suspend fun <T> Call<T>.await(): T {
        return suspendCoroutine { continuation ->
            enqueue(object : Callback<T> {
                override fun onResponse(call: Call<T>, response: Response<T>) {
                    val body = response.body()
                    if (body != null) continuation.resume(body)
                    else continuation.resumeWithException(
                        RuntimeException("response body is null")
                    )
                }

                override fun onFailure(call: Call<T>, t: Throwable) {
                    continuation.resumeWithException(t)
                }
            })
        }
    }
}